using System;
using System.Collections.Generic;
using System.Text;

using SharksHunter.Domain.Model;
using SharksHunter.TransferObjects.Model;
using SharksHunter.TransferObjects.Presentation;

namespace SharksHunter.Service
{
    public class HunterCollectionService: Interfaces.IHunterCollectionService
    {
        #region MEMBERS
        private SharksHunter.DAO.Interfaces.ICollectionPersistence  _collPersist;
        private SharksHunter.Domain.Model.Collection                _currentCollection;
        private System.Collections.Generic.SortedList<string, SharksHunter.Domain.Model.Collection> 
                                                                    CollectionRepository;
        #endregion

        #region CTOR
        public HunterCollectionService()
        {
            _collPersist = new SharksHunter.DAO.StorageHandlers.FileStorage.FileStorageHandler();
            CollectionRepository = new System.Collections.Generic.SortedList<string, SharksHunter.Domain.Model.Collection>();
        }
        #endregion

        #region IHunterService

        #region COLLECTION
        SharksHunter.Domain.Model.Collection[] Interfaces.IHunterCollectionService.GetAvailableCollection()
        {return null;}

        SharksHunter.Domain.Model.Collection Interfaces.IHunterCollectionService.OpenCollection(SharksHunter.TransferObjects.Presentation.IParamProvider pprov)
        {
            string colpath = pprov.QueryParam(ParamsNames.FileNames)[0];
            SharksHunter.Domain.Model.Collection col = new SharksHunter.Domain.Model.Collection();
            this._collPersist.OpenCollection(ref col, colpath);
            
            CollectionRepository.Add(col.Name, col);

            SwitchToCollection(col.Name);

            return col;
        }
        
        SharksHunter.Domain.Model.Collection Interfaces.IHunterCollectionService.NewCollection(SharksHunter.TransferObjects.Presentation.IParamProvider pprov)
        {
            string colname = pprov.QueryParam(ParamsNames.CollectionName)[0];
            if(this.CollectionRepository.ContainsKey(colname) == false)
            {
                SharksHunter.Domain.Model.Collection col = new SharksHunter.Domain.Model.Collection();
                col.Name = colname;
                col.Description = pprov.QueryParam(ParamsNames.CollectionDescription)[0];
                col.Path = pprov.QueryParam(ParamsNames.CollectionPath)[0];

                CollectionRepository.Add(colname, col);
                
                SwitchToCollection(colname);

                return col;
            }
            return null;
        }
        void Interfaces.IHunterCollectionService.SaveCollection()
        {
            this._collPersist.SaveCollection(this.CurrentCollection);
        }

        IList<SharksHunter.Domain.Model.Collection> Interfaces.IHunterCollectionService.CollectionList
        {
            get
            {
                return this.CollectionRepository.Values;
            }
        }

        
        public SharksHunter.Domain.Model.Collection SwitchToCollection(string name)
        {
            if(this.CollectionRepository.ContainsKey(name))
                _currentCollection = this.CollectionRepository[name];
            else
                throw new SharksHunter.TransferObjects.Exceptions.CollectionNotFoundException(name);

            return _currentCollection;
        }

        public SharksHunter.Domain.Model.Collection CurrentCollection
        {
            get 
            { 
                if(_currentCollection == null)
                    throw new SharksHunter.TransferObjects.Exceptions.CollectionNotFoundException("");

                return _currentCollection; 
            }
        }

        #endregion

        #region ENTITY
        public SharksHunter.Domain.Model.Entity NewEntity(string name, SharksHunter.Service.Interfaces.IScanner<ItemTO> scanner)
        {
            Entity ent = new Entity();
            ent.Name = name;
            this.CurrentCollection.Entities.Add(ent);

            foreach(ItemTO itemto in scanner.Scan())
            {
                Shot shot = FindShotByName(ent.Shots, itemto.Shot);
                if (shot == null)
                {
                    shot = new Shot();
                    shot.Name = itemto.Shot;
                    ent.Shots.Add(shot);
                }
                Item item = new Item();
                item.Name = itemto.Name;
                item.Size = itemto.Size;
                item.CRC32 = itemto.CRC32;
                shot.Items.Add(item);
            }

            return ent;
        }
        
        public SharksHunter.TransferObjects.Model.ItemTO[] FetchItems(string entity, long size)
        {
            List<SharksHunter.TransferObjects.Model.ItemTO> itlist = new List<SharksHunter.TransferObjects.Model.ItemTO>();
            foreach(Entity ent in this.CurrentCollection.Entities)
            {
                if(ent.Name == entity)
                {
                    foreach(Shot sh in ent.Shots)
                    {
                        foreach(Item it in sh.Items)
                        {
                            if(it.Size == size)
                                itlist.Add(CreateTOItem(it));
                        }
                    }
                    break;
                }
            }
            return itlist.ToArray();
        }

        #endregion

        #region HUNT
        public List<SharksHunter.TransferObjects.Model.HuntInfo> GetHuntInfo()
        {
            List<SharksHunter.TransferObjects.Model.HuntInfo> list = new List<SharksHunter.TransferObjects.Model.HuntInfo>();
            foreach(Entity ent in this.CurrentCollection.SelectedEntities)
            {
                int c = 0;
                HuntInfo hi = new HuntInfo(ent.Name);
                list.Add(hi);
                foreach(string p in ent.SelectedIncomingFolders)
                {
                    hi.IncomingFolders.Add(p);
                    c++;
                }
                if(c == 0)//no incoming folders on entity level
                {
                    foreach(string p in CurrentCollection.SelectedIncomingFolders)
                    {
                        hi.IncomingFolders.Add(p);
                    }
                }
            }
            return list;
        }
        #endregion

        #endregion

        #region MEMBERS



        #endregion

        #region PRIVATE
        private Shot FindShotByName(List<Shot> list, string name)
        {
            foreach (Shot s in list)
            {
                if (s.Name == name)
                    return s;
            }
            return null;
        }

        private ItemTO CreateTOItem(Item it)
        {
            ItemTO itto = new ItemTO();
            itto.Name = it.Name;
            itto.Size = it.Size;
            itto.CRC32 = it.CRC32;
            return itto;
        }
        #endregion
    }
}
